package com.njcb.ams.support.trade.filter;

import com.njcb.ams.support.annotation.TradeFilter;
import com.njcb.ams.support.annotation.Trader;
import com.njcb.ams.support.annotation.enums.TradeType;
import com.njcb.ams.support.exception.ExceptionUtil;
import com.njcb.ams.support.trade.TradeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 * @author liuyanlong
 * 类功能描述：默认集成交易的事务传播控制
 */
@Service
@Lazy(false)
@TradeFilter(priority = 0)
public class ServiceTransactionFilter implements TradeLayerFilter {
    private static final Logger logger = LoggerFactory.getLogger(ServiceTransactionFilter.class);
    @Autowired
    private PlatformTransactionManager transactionManager;

    @Override
    public Object doFilter(TradeFilterChain filterChain) throws Throwable {
        Trader anm = filterChain.getTraderAnnotation();
        TransactionStatus status = null;
        Object result = null;
        try {
            if (TradeType.TYPE_TRANS == anm.tradeType()) {
                DefaultTransactionDefinition def = new DefaultTransactionDefinition();
                def.setPropagationBehavior(anm.propagation().value());
                status = transactionManager.getTransaction(def);
                if (null == status) {
                    ExceptionUtil.throwAppException("TransactionStatus获取失败");
                }
            }
            result = filterChain.doFilter(filterChain);
            if (TradeType.TYPE_TRANS == anm.tradeType()) {
                if (TradeUtil.isRollbackOnly()) {
                    transactionManager.rollback(status);
                    logger.debug("交易[{}]流水[{}]事务回滚", anm.tradeCode(), TradeUtil.getReqSeq());
                } else {
                    transactionManager.commit(status);
                    logger.debug("交易[{}]流水[{}]事务提交", anm.tradeCode(), TradeUtil.getReqSeq());
                }
            }
        } catch (Throwable e) {
            ExceptionUtil.printStackTrace(e);
            if (TradeType.TYPE_TRANS == anm.tradeType()) {
                transactionManager.rollback(status);
                logger.debug("交易[{}]流水[{}]事务回滚", anm.tradeCode(), TradeUtil.getReqSeq());
            }
            throw e;
        } finally {
            if (null != transactionManager && null != status && !status.isCompleted()) {
                transactionManager.rollback(status);
                logger.warn("交易[{}]流水[{}]事务未完结自动回滚", anm.tradeCode(), TradeUtil.getReqSeq());
            }
        }

        return result;
    }

}
